package top.raoqq.sky.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import top.raoqq.sky.constant.SkyConstant;
import top.raoqq.sky.dto.MenuDTO;
import top.raoqq.sky.dto.MenuTreeDTO;
import top.raoqq.sky.entity.sql.Menu;
import top.raoqq.sky.mapper.MenuMapper;
import top.raoqq.sky.service.CommonService;
import top.raoqq.sky.service.MenuService;

import java.util.ArrayList;
import java.util.List;

/**
 * @author 饶奇奇
 * @date 2023/8/16
 */
@Service
@RequiredArgsConstructor
public class MenuServiceImpl extends ServiceImpl<MenuMapper, Menu> implements MenuService {

    @Override
    public List<MenuTreeDTO> listMenuTree() {
        LambdaQueryWrapper<Menu> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Menu::getVisible, SkyConstant.MENU_SHOW);
        wrapper.select(Menu::getMenuId, Menu::getParentId, Menu::getMenuName);
        List<Menu> menuList = baseMapper.selectList(null);
        List<MenuTreeDTO> menuTreeDTOList = new ArrayList<>(16);
        buildMenuTree(menuList, menuTreeDTOList);
        return menuTreeDTOList ;
    }

    @Override
    public List<Menu> listMenu() {
        List<Menu> menuList = baseMapper.selectList(null);
        return menuList2Tree(menuList);
    }

    private List<Menu> menuList2Tree(List<Menu> menuList) {
      List<Menu> result = new ArrayList<>();
      menuList.forEach(menu -> {
          if (Long.valueOf(0).equals(menu.getParentId())) {
              result.add(menu);
          }
      });
      makeChildren(menuList, result);
      return result;
    }

    private void buildMenuTree(List<Menu> menuList, List<MenuTreeDTO> menuTreeDTOList) {
        // 获取第一层
        menuList.forEach(menu -> {
            if (Long.valueOf(0).equals(menu.getParentId())) {
                MenuTreeDTO menuTreeDTO = MenuTreeDTO.cloneByMenu(menu);
                menuTreeDTOList.add(menuTreeDTO);
            }
        });
        setChildren(menuList, menuTreeDTOList);
    }

    private void makeChildren(List<Menu> menuList, List<Menu> result) {
        result.forEach(item -> {
            List<Menu> children = new ArrayList<>();
            for (Menu menu : menuList) {
                if (item.getMenuId().equals(menu.getParentId())) {
                    children.add(menu);
                }
            }

            if (!CollectionUtils.isEmpty(children)) {
                makeChildren(menuList, children);
                item.setChildren(children);
            }
        });
    }

    private void setChildren(List<Menu> menuList, List<MenuTreeDTO> menuTreeDTOList) {
        menuTreeDTOList.forEach(menuTreeDTO -> {
            List<MenuTreeDTO> children = new ArrayList<>();
            for (Menu menu : menuList) {
                if (menu.getParentId().equals(menuTreeDTO.getId())) {
                    children.add(MenuTreeDTO.cloneByMenu(menu));
                }
            }
            if (!CollectionUtils.isEmpty(children)) {
                setChildren(menuList, children);
                menuTreeDTO.setChildren(children);
            }
        });
    }
}
